﻿using Frameworks;
using Google.Protobuf;
using System;
using System.Collections.Generic;

namespace DotNetClient
{
    public class NetworkManager : Singleton<NetworkManager>
    {
        private NetworkManager() { }

        public override void OnSingletonInit()
        {
            base.OnSingletonInit();

            _msgQueue = new Queue<Message>();

            // 将回调的 Key 和 托管函数 对应起来
            CallbackFactory.Instance.RegistCallbacks(); // 客户端请求响应
            BroadcastFactory.Instance.RegistEvents(); // 服务器广播
        }

        public override void Dispose()
        {
            _client?.Disconnect();
            base.Dispose();
        }

        private SocketClient _client;       // 
        private Queue<Message> _msgQueue;  // 消息队列

        public string host { get; private set; }
        public int port { get; private set; }

        /// <summary>
        /// 建立起一条新的连接
        /// </summary>
        public void InitClient(string host, int port, Action onInit)
        {
            this.host = host;
            this.port = port;

            _client = new SocketClient();
            _client.NetWorkStateChangedEvent += (state) =>
            {
                UnityEngine.Debug.Log("Connector NetWorkStateChangedEvent: " + state);
            };

            _client.InitClient(this.host, this.port, () =>
            {
                _client.Connect(() =>
                {
                    onInit?.Invoke();
                });

                // 注册广播事件的名称
                foreach (KeyValuePair<string, Action<Message>> pair in BroadcastFactory.Instance.Callbacks)
                {
                    RegistBroadcast(pair.Key);
                }
            });
        }

        /// <summary>
        /// 向服务器发通知,无响应
        /// </summary>
        /// <param name="route"></param>
        /// <param name="message"></param>
        public void Notify(string route, IMessage message)
        {
            _client.Notify(route, message);
        }

        /// <summary>
        /// 向服务器发请求,有响应
        /// </summary>
        /// <param name="route"></param>
        /// <param name="message"></param>
        public void Request(string route, IMessage message)
        {
            _client.Request(route, message, (data) =>
            {
                _msgQueue.Enqueue(data);
            });
        }

        /// <summary>
        /// 注册了 广播事件的 处理逻辑
        /// </summary>
        /// <param name="eventName"></param>
        public void RegistBroadcast(string eventName)
        {
            _client.On(eventName, (data) =>
            {
                //data.route = eventName;
                //data.type = MessageType.MSG_PUSH;
                _msgQueue.Enqueue(data);
            });
        }

        /// <summary>
        /// 处理消息队列
        /// </summary>
        public void Update()
        {
            while (_msgQueue.Count > 0)
            {
                Message msg = _msgQueue.Dequeue();
                if (string.IsNullOrEmpty(msg.route))
                {
                    UnityEngine.Debug.LogError("cannt find route in msg");
                    continue;
                }

                switch (msg.type)
                {
                    case MessageType.MSG_REQUEST: break;
                    case MessageType.MSG_NOTIFY: break;
                    case MessageType.MSG_RESPONSE: CallbackFactory.Instance.InvokeHandle(msg.route, msg); break;
                    case MessageType.MSG_PUSH: BroadcastFactory.Instance.InvokeHandle(msg.route, msg); break;
                    default: break;
                }
            }
        }

    }
}
